<?php

namespace common\widgets;

use kartik\base\AddonTrait;
use yii\widgets\InputWidget;
use Yii;
use yii\base\InvalidConfigException;
use yii\helpers\Html;
use yii\helpers\Inflector;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;
use yii\web\JsExpression;
use yii\web\View;
use metronic\MultipleSelectAsset;

/**
 * Select2 widget is a Yii2 wrapper for the Select2 jQuery plugin. This input widget is a jQuery based replacement for
 * select boxes. It supports searching, remote data sets, and infinite scrolling of results. The widget is specially
 * styled for Bootstrap 3.x and Bootstrap 4.x.
 *
 * @author Kartik Visweswaran <kartikv2@gmail.com>
 * @since 1.0
 * @see https://github.com/select2/select2
 */
class Select2Input extends InputWidget {

    /**
     * @var array $data the option data items. The array keys are option values, and the array values are the
     * corresponding option labels. The array can also be nested (i.e. some array values are arrays too). For each
     * sub-array, an option group will be generated whose label is the key associated with the sub-array. If you
     * have a list of data models, you may convert them into the format described above using [[ArrayHelper::map()]].
     */
    public $data;

    /**
     * @var array $data the option data items. The array keys are option values, and the array values are the
     * corresponding option labels. The array can also be nested (i.e. some array values are arrays too). For each
     * sub-array, an option group will be generated whose label is the key associated with the sub-array. If you
     * have a list of data models, you may convert them into the format described above using [[ArrayHelper::map()]].
     */
    public $pluginOptions = [
        'multiple' => true
    ];

    /**
     * @inheritdoc
     * @throws \ReflectionException
     * @throws \yii\base\InvalidConfigException
     */
    public function run() {
        parent::run();
        $this->renderWidget();
    }

    /**
     * Initializes and renders the widget
     * @throws \ReflectionException
     * @throws \yii\base\InvalidConfigException
     */
    public function renderWidget() {
        $multiple = ArrayHelper::getValue($this->pluginOptions, 'multiple', false);
        $multiple = ArrayHelper::getValue($this->options, 'multiple', $multiple);
        $this->options['multiple'] = $multiple;

        if (!isset($this->data)) {
            if (!isset($this->value) && !isset($this->initValueText)) {
                $this->data = [];
            } else {
                if ($multiple) {
                    $key = isset($this->value) && is_array($this->value) ? $this->value : [];
                } else {
                    $key = isset($this->value) ? $this->value : '';
                }
                $val = isset($this->initValueText) ? $this->initValueText : $key;
                $this->data = $multiple ? array_combine((array) $key, (array) $val) : [$key => $val];
            }
        }

        $this->registerAssets();
        $this->renderInput();
    }

    /**
     * Renders the source Input for the Select2 plugin. Graceful fallback to a normal HTML select dropdown or text
     * input - in case JQuery is not supported by the browser
     * @throws InvalidConfigException
     */
    protected function renderInput() {
        echo Html::activeDropDownList($this->model, $this->attribute, $this->data, $this->options);
    }

    /**
     * Registers the client assets for [[Select2]] widget.
     */
    public function registerAssets() {
        $id = $this->options['id'];
        $isMultiple = isset($this->options['multiple']) && $this->options['multiple'];
        $options = Json::encode([
            'selectableOptgroup' => $isMultiple,
        ]);
        $view = $this->getView();
        MultipleSelectAsset::register($view);
        $view->registerJs("jQuery('#{$id}').multiSelect({$options});");
    }

}
